package com.fz.song.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fz.song.framework.exceptions.ServerException;
import com.fz.song.web.entity.User;
import com.fz.song.web.mapper.UserMapper;
import com.fz.song.web.service.IUserMsgService;
import com.fz.song.web.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 宋发准
 * @since 2021-11-01
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {


    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IUserMsgService userMsgService;


    @Override
    public User getByIdCard(String idCard) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getIdCard, idCard);
        return getOne(wrapper);
    }

    @Override
    @Transactional
    public Boolean transferOptimistic(int fromId, int toId, int money) {
        User from = getById(fromId);
        User to = getById(toId);
        //获取版本号,在执行update语句的时候注意校验版本号要一致,当然要注意ABA的问题
        int fromNum = userMapper.updateUserMoneyBySub(from.getId(), money, from.getVersion());
        int toNum = userMapper.updateUserMoneyByAdd(to.getId(), money, to.getVersion());
        if (fromNum <= 0 || toNum <= 0) {
            throw new ServerException(1000, "转账异常");
        }
        return true;
    }


    @Override
    @Transactional
    public Boolean transferPessimism(int fromId, int toId, int money) {

        //使用 在查询语句后加sql[for update]   加锁
        User from = userMapper.getByIdForUpdate(fromId);
        //使用 在查询语句后加sql[for update]   加锁
        User to = userMapper.getByIdForUpdate(toId);
        //记录锁定后操作数据
        int fromNum = userMapper.transferPessimismSub(fromId, money);
        int toNum = userMapper.transferPessimismAdd(toId, money);
        if (fromNum <= 0 || toNum <= 0) {
            throw new ServerException(1000, "转账异常");
        }
        return true;
    }


}
